import { platform } from "../../Config/Platform";
/**
 * protobuf编码解码器
 * */

class ProtobufTools {
  // version = null; //传给服务器的版本信息，保存在platform.json下
  proto = null;

  init(callback) {
    if (this.proto) {
      callback(true);
      return;
    }

    // this.version = require("Platform");
    this.initProto(callback);
  }

  initProto(callback) {
    let pbkiller = require("pbkiller");
    var self = this;
    var load = function () {
      self.proto = pbkiller.loadFromFile("hallmsg.proto");
      if (callback) {
        callback(true);
      }
    };

    // if (cc.sys.platform === cc.sys.WECHAT_GAME || cc.sys.isMobile) {
    pbkiller.preload(function () {
      load();
    });
    // } else {
    //     load()
    // }
  }

  encode(data) {
    var cmd = data.cmd;
    delete data.cmd;

    //消息公共头
    var ClientMsgHead = new this.proto["ClientMsgHead"]();
    ClientMsgHead.msgname = cmd + "Req";
    ClientMsgHead.svr_id = "";
    ClientMsgHead.service_address = 0;
    ClientMsgHead.msgtype = 1;
    var clientHead = ClientMsgHead.toArrayBuffer();

    //公有消息的version信息
    var DataMsg = new this.proto[cmd + "Req"]();
    var protoChildType = DataMsg["__proto__"]["$type"]["children"]; // 协议字段默认类型
    var protoTypes = {};
    protoChildType.forEach(function (data) {
      protoTypes[data.name] = data.type.name;
    });

    // 插入游戏服务器信息
    /*
            id: game_info.id,
            roomsvr_id: game_info.roomsvr_id,
            roomsvr_table_address: game_info.roomsvr_table_address,
            gameid: gameid
        * */

    for (var key in data) {
      var value = data[key];
      var valueType = typeof value;

      if (
        value != undefined &&
        (protoTypes[key] == "int32" || protoTypes[key] == "int64") &&
        valueType == "string"
      ) {
        value = parseInt(value);
      } else if (
        value != undefined &&
        protoTypes[key] == "string" &&
        valueType == "number"
      ) {
        value = value + "";
      }
      DataMsg[key] = value;
    }
    //  console.log("_______version.CHANNE = "+this.version.CHANNEL);
    DataMsg.version = {
      platform: cc.vv.platform.PLATFORM, //client 平台id(属于哪家公司发行)
      channel: cc.vv.platform.CHANNEL, //client 渠道id(发行公司的发行渠道)
      version: cc.vv.platform.VERSION, //client 版本号
      // authtype: cc.vv.GLNetDataModel.auth_type || 1, //client 账号类型
      regfrom: cc.vv.platform.REGFROM, //描述从哪里注册过来的
      clienttype: 2
    };
    var dataMsg = DataMsg.toArrayBuffer();

    var c = cc.vv.core.convertIntToUInt8Array(clientHead.byteLength);
    clientHead = cc.vv.core.arraybuffer2array(clientHead);
    dataMsg = cc.vv.core.arraybuffer2array(dataMsg);

    var message = c.concat(clientHead, dataMsg);
    message = cc.vv.core.array2arraybuffer(message);
    return message;
  }

  decode(d, callback) {
    var self = this;
    // cc.vv.core.blobToArrayBuffer(data, function (d) {
    var dd = self._decode(d);

    // if (dd.errcode == undefined) {
    //   // 做个默认处理
    //   dd.errcode = 0;
    // }

    if (callback) {
      callback(dd);
    }
    // })
  }

  _decode(arrayBuffer) {
    var data = cc.vv.core.arraybuffer2array(arrayBuffer);
    // var string = cc.vv.GLUtils.binarraytoString(arrayBuffer)
    // cc.error("_sss_??? data decode ", string);
    var len = data.length;
    if (len < 2) {
      cc.error("proto is too short!");
      return null;
    }

    var headLenArray = cc.vv.core.getArrayFromArray(data, 0, 2);
    var headLen = cc.vv.core.convertUInt8ArrayToInt(headLenArray);
    if (headLen <= 0) {
      cc.error("proto head len is too short!");
      return;
    }

    var ClientMsgHead = this.proto["ClientMsgHead"];
    var clientHeadArray = cc.vv.core.getArrayFromArray(data, 2, headLen);
    var clientHead = ClientMsgHead.decode(clientHeadArray);
    if (!clientHead) {
      cc.error("proto head decode wrong!");
      return null;
    }

    // function buf2hex(buffer) { // buffer is an ArrayBuffer
    //     return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
    //   }

    var name = clientHead.msgname;
    // if(name == "EnterTableRes"){
    //     console.log("size:"+ data.length, "md5:",buf2hex(arrayBuffer))
    // }
    // cc.log("clientHead.msgname",clientHead.msgname)
    if (!name) {
      cc.error("proto head decode null name!");
      return null;
    }

    var builder = this.proto[name];
    if (!builder) {
      cc.error("proto head name not in proto(!" + name + ")");
      return null;
    }

    // console.log("_sss____name = " + name);

    var bodyArray = cc.vv.core.getArrayFromArray(data, 2 + headLen);
    var body = builder.decode(bodyArray); //builder.builder.deserializeBinary(bodyArray)

    console.log("\n\n\n ProtobufTools_ message_STC= " + name + JSON.stringify(body), new Date(), cc.vv.GLDefine.isInBack);
    if (!body) {
      cc.error("proto body decode wrong!");
      return null;
    }

    body.is_ntc = false;
    var suffix = name.substring(name.length - 3);
    var name = name.substring(0, name.length - 3);
    if (suffix == "Ntc") {
      body.is_ntc = true;
      name = name + suffix;
    }
    body.builder = builder.builder_name;
    body.cmd = name;

    return body;
  }
}

export let protobufTools: ProtobufTools = new ProtobufTools();
